package com.miao.im.core.exception;

import com.miao.im.common.annotation.SocketAdvice;
import lombok.Getter;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ClassUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @Auther: miaoguoxin
 * @Date: 2021/3/19 14:37
 * @Description:
 */
@Getter
public class SocketAdviceBean {

    private String beanName;

    private Class<?> beanType;

    private Object bean;

    public SocketAdviceBean(String beanName, BeanFactory beanFactory) {
        this.beanName = beanName;
        this.beanType = getBeanType(beanName, beanFactory);
        this.bean = beanFactory.getBean(beanName);
    }

    private static Class<?> getBeanType(String beanName, BeanFactory beanFactory) {
        Class<?> beanType = beanFactory.getType(beanName);
        return (beanType != null ? ClassUtils.getUserClass(beanType) : null);
    }

    /**
     * 搜索全部的注解bean
     * @author miaoguoxin
     * @date 2021/3/19
     */
    public static List<SocketAdviceBean> findAnnotatedBeans(ApplicationContext context) {
        List<SocketAdviceBean> adviceBeans = new ArrayList<>();
        for (String name : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, Object.class)) {
            if (!ScopedProxyUtils.isScopedTarget(name)) {
                SocketAdvice advice = context.findAnnotationOnBean(name, SocketAdvice.class);
                if (advice != null) {
                    adviceBeans.add(new SocketAdviceBean(name, context));
                }
            }
        }
        if (adviceBeans.size() > 1) {
            throw new IllegalArgumentException("不允许多个@SocketAdvice存在");
        }
        return adviceBeans;
    }
}
